﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls.Base;
using Silvermoon.Shapes;
using System.Drawing;
using Silvermoon.Images;
using Silvermoon.Windows;
using Silvermoon.UI;
using Silvermoon.OpenGL;

namespace Silvermoon.Controls
{
    public class RadioButton : ToggleButtonBase
    {
        #region fields

        private Shape content;
        private Shape radioShape;

        #endregion
        #region accessors

        public static PropertyAccessor<RadioButton, Color> CheckColorProperty = PropertyAccessor.Register<RadioButton, Color>(
            "CheckColor",
            c => c.CheckColor,
            (c, v) => c.CheckColor = v);

        public static PropertyAccessor<RadioButton, int> CheckOpacityProperty = PropertyAccessor.Register<RadioButton, int>(
    "CheckOpacityColor",
    c => c.CheckOpacity,
    (c, v) => c.CheckOpacity = v);

        #endregion
        #region statics


        static RadioButton()
        {
            VisualStateManager.RegisterClassManager(typeof(RadioButton), ButtonStateManagers.RadioButtonManager);
        }
        #endregion
        #region ctor/dtor
        public RadioButton()
            : base()
        {
            Height = 64;
        }

        protected override void Dispose(bool dispose)
        {
            if (radioShape != null) radioShape.Dispose();
            if (content != null) content.Dispose();
            base.Dispose(dispose);
        }

        #endregion
        #region props

        protected int CheckOpacity
        {
            get { return radioShape != null ? radioShape.Opacity : 0; }
            set
            {
                if (radioShape != null && radioShape.Opacity != value)
                {
                    radioShape.Opacity = value;
                    Invalidate(InvalidationFlag.Appearance);
                }
            }
        }

        protected Color CheckColor
        {
            get { return radioShape != null ? radioShape.Color : Color.Empty; }
            set
            {
                if (radioShape != null && radioShape.Color != value)
                {
                    radioShape.Color = value;
                    Invalidate(InvalidationFlag.Appearance);
                }
            }
        }

        public Shape Content
        {
            get { return content; }
            set
            {
                if (content != value)
                {
                    if (content != null) content.Dispose();
                    CheckAlignment(value);
                    content = value;
                    OnColorChanged();
                }
            }
        }

        public Shape RadioShape
        {
            get { return radioShape; }
            set
            {
                if (radioShape != value)
                {
                    if (radioShape != null) radioShape.Dispose();
                    radioShape = value;
                    OnRadioChanged();
                }
            }
        }

        protected override Rectangle BackgroundRect
        {
            get
            {
                if (Background == null) return Rectangle.Empty;
                Size size = Background.Size;
                return new Rectangle(0, (Height - size.Height) / 2, size.Width, size.Height);
            }
        }

        protected virtual Rectangle RadioRect
        {
            get
            {
                if (radioShape == null) return Rectangle.Empty;

                Rectangle r = BackgroundRect;
                if (!r.IsEmpty)
                {
                    Size size = radioShape.Size;
                    return new Rectangle((r.Width - size.Width) / 2 + r.Left, (r.Height - size.Height) / 2 + r.Top, size.Width, size.Height);
                }
                else return Rectangle.Empty;
            }
        }

        protected virtual Rectangle ContentRect
        {
            get
            {
                if (Background == null) return ClientBounds;
                Size size = content.Size;
                int x = BackgroundRect.Width + 16;
                int y = (Height - size.Height) / 2;
                int w = Width - x;
                if (w < size.Width) w = size.Width;
                // return new Rectangle(x, y, w, size.Height);
                return new Rectangle(x, 0, Width - x, Height);
            }
        }

        #endregion
        #region methods

        protected override void OnToggleButtonTap(TapEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
                if (Enabled && !IsChecked) IsChecked = true;
            }
        }

        private void CheckAlignment(Shape shape)
        {
            StringShape stringShape = shape as StringShape;
            if (stringShape != null)
            {
                stringShape.Alignment = Alignment.Near;
                stringShape.LineAlignment = Alignment.Center;
            }
        }

        protected virtual void OnRadioChanged()
        {
            Invalidate(InvalidationFlag.LayoutAppearance);
        }

        protected virtual void OnContentChanged()
        {
            Invalidate(InvalidationFlag.LayoutAppearance);
        }

        protected override void OnLayout()
        {
            base.OnLayout();
            if (CheckFlag(InvalidationFlag.Size | InvalidationFlag.Layout))
            {
                if (radioShape != null) radioShape.Bounds = RadioRect;
                if (content != null) content.Bounds = ContentRect;
            }
            if (CheckFlag(InvalidationFlag.Layout))
            {
                Shapes.Clear();
                Shapes.AddLast(Background); // checks for null.
                Shapes.AddLast(radioShape);
                Shapes.AddLast(content);
            }
            if (CheckFlag(InvalidationFlag.Appearance))
            {
                if (radioShape != null) radioShape.Visible = IsChecked;
            }
        }

        protected override void OnCheckedChanged()
        {
            if (IsChecked)
            {
                UncheckSiblings();
            }
            base.OnCheckedChanged();
        }

        private void UncheckSiblings()
        {
            Control parent = this.Parent;
            if (parent != null)
            {
                ControlCollection children = parent.VisibleControls;
                if (children != null)
                {
                    Control child = children.First;
                    while (child != null)
                    {
                        RadioButton radio = child as RadioButton;
                        if (radio != null && radio != this) radio.IsChecked = false;
                        child = child.NextControl;
                    }
                }
            }
        }

        protected override Shape CreateDefaultBackground()
        {
            //return new BackgroundShape { Texture = SysImages.RadioBackground, Size = new Size(48, 48), Style = RenderStyle.Simple };
            return new BackgroundShape { Texture = SysImages.RoundButton, Size = Control.ScaledSize(48, 48), Style = RenderStyle.Simple };
        }

        protected virtual Shape CreateRadioShape()
        {
            return new TrackbarButtonShape { Color = PhoneColors.Accent, Size = Control.ScaledSize(28, 28) };
        }

        protected override void ApplyStyle()
        {
            base.ApplyStyle();
            if (radioShape == null) radioShape = CreateRadioShape();
            if (Color.IsEmpty) Color = Color.Gainsboro;

        }

        #endregion
    }
}
